def get_valid_input(prompt, validation_func, error_message='输入无效，请重新输入。'):
    while True:
        value = input(prompt).strip()
        if validation_func(value):
            return value
        print(error_message)


def is_non_empty(value):
    return bool(value)


def is_digit(*args):
    for arg in args:
        if not arg.isdigit():
            return False
    return True


def is_valid_email(value):
    return '@' in value and '.' in value


def is_leap_year(year):
    """ 判断输入字符是否是闰年

    :param year: 年份
    :return: 是否是闰年
    """
    if not is_digit(year):
        return False

    year = int(year)
    return not year % 4 and year % 100 or not year % 400


def is_standard_date_format(date: str):
    """ 判断输入的日期是否是yyyy-MM-dd格式

    :param date: 日期
    :return: 是否是yyyy-MM-dd格式
    """
    sp = date.split('-')
    if len(sp) != 3 or not is_digit(sp[0], sp[1], sp[2]) or len(sp[1]) != 2 or len(sp[2]) != 2:
        return False

    days = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
    if is_leap_year(sp[0]):
        days[2] += 1

    return 0 < int(sp[1]) < 13 and 0 < int(sp[2]) <= days[int(sp[1])]


def date_to_day_of_year(date: str):
    """ 用于计算输入的日期是其所在年的第几天

    :param date: 日期
    :return: 其所在年的第几天
    """
    if not is_standard_date_format(date):
        return -1
    sp = date.split('-')
    days = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
    if is_leap_year(sp[0]):
        days[2] += 1
    return sum(days[:int(sp[1])]) + int(sp[2])
